<?php

namespace App\Http\Controllers\Admin\Finance\Receivable;

use App\Http\Controllers\Controller;
use App\Models\finance\ReceivableTemplate1Model;
use App\Models\TakeOrderModel;
use App\Exports\ReceivableTemplate1Export;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel;

class Template1 extends Controller
{
    /**
     * 模板1应收账款列表
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function list(Request $request): JsonResponse
    {
        $query = ReceivableTemplate1Model::with(['take_order', 'create_admin']);
        
        // 筛选条件
        if ($request->filled('take_order_id')) {
            $query->where('take_order_id', $request->input('take_order_id'));
        }
        
        if ($request->filled('take_order_sn')) {
            $takeOrderIds = TakeOrderModel::where('sn', 'like', '%' . $request->input('take_order_sn') . '%')
                ->pluck('id')
                ->toArray();
            if (!empty($takeOrderIds)) {
                $query->whereIn('take_order_id', $takeOrderIds);
            }
        }
        
        if ($request->filled('origin')) {
            $query->where('origin', 'like', '%' . $request->input('origin') . '%');
        }
        
        if ($request->filled('destination')) {
            $query->where('destination', 'like', '%' . $request->input('destination') . '%');
        }
        
        if ($request->filled('status')) {
            $query->where('status', $request->input('status'));
        }
        
        if ($request->filled('currency')) {
            $query->where('currency', $request->input('currency'));
        }
        
        if ($request->filled('business_date_start') && $request->filled('business_date_end')) {
            $query->whereBetween('business_date', [$request->input('business_date_start'), $request->input('business_date_end')]);
        }
        
        if ($request->filled('date_start') && $request->filled('date_end')) {
            $query->whereBetween('created_at', [$request->input('date_start'), $request->input('date_end') . ' 23:59:59']);
        }
        
        // 分页
        $per_page = $request->input('per_page', 15);
        $list = $query->orderBy('id', 'desc')->paginate($per_page);
        
        return $this->success([
            'list' => $list->items(),
            'total' => $list->total(),
        ]);
    }
    
    /**
     * 添加模板1应收账款
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function add(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'business_date' => 'required|date',
            'take_order_sn' => 'required|string',
            'origin' => 'required|string|max:100',
            'destination' => 'required|string|max:100',
            'charging_weight' => 'required|numeric|min:0',
            'currency' => 'required|string|max:20',
            'gross_weight' => 'nullable|numeric|min:0',
            'volume_weight' => 'nullable|numeric|min:0',
            'big_package' => 'nullable|integer|min:0',
            'volume' => 'nullable|numeric|min:0',
            'air_freight_unit_price' => 'nullable|numeric|min:0',
            'air_freight' => 'nullable|numeric|min:0',
            'master_bill_fee' => 'nullable|numeric|min:0',
            'electricity_check_fee' => 'nullable|numeric|min:0',
            'operation_fee_charging_weight' => 'nullable|numeric|min:0',
            'charter_fee' => 'nullable|numeric|min:0',
            'hk_registration_fee' => 'nullable|numeric|min:0',
            'cross_border_transfer_fee' => 'nullable|numeric|min:0',
            'insurance_fee' => 'nullable|numeric|min:0',
            'sea_freight' => 'nullable|numeric|min:0',
            'ground_operation_fee_air' => 'nullable|numeric|min:0',
            'total_amount' => 'nullable|numeric|min:0',
        ], [
            'business_date.required' => '业务日期不能为空',
            'business_date.date' => '业务日期格式不正确',
            'take_order_sn.required' => '主单号不能为空',
            'take_order_sn.string' => '主单号必须是字符串',
            'origin.required' => '起始港不能为空',
            'origin.string' => '起始港必须是字符串',
            'origin.max' => '起始港不能超过100个字符',
            'destination.required' => '目的港不能为空',
            'destination.string' => '目的港必须是字符串',
            'destination.max' => '目的港不能超过100个字符',
            'charging_weight.required' => '计费重不能为空',
            'charging_weight.numeric' => '计费重必须是数字',
            'charging_weight.min' => '计费重不能小于0',
            'currency.required' => '币种不能为空',
            'currency.string' => '币种必须是字符串',
            'currency.max' => '币种不能超过20个字符',
            'gross_weight.numeric' => '毛重必须是数字',
            'gross_weight.min' => '毛重不能小于0',
            'volume_weight.numeric' => '体积重必须是数字',
            'volume_weight.min' => '体积重不能小于0',
            'big_package.integer' => '大包数量必须是整数',
            'big_package.min' => '大包数量不能小于0',
            'volume.numeric' => '体积必须是数字',
            'volume.min' => '体积不能小于0',
            'air_freight_unit_price.numeric' => '空运单价必须是数字',
            'air_freight_unit_price.min' => '空运单价不能小于0',
            'air_freight.numeric' => '空运费必须是数字',
            'air_freight.min' => '空运费不能小于0',
            'master_bill_fee.numeric' => '主单费必须是数字',
            'master_bill_fee.min' => '主单费不能小于0',
            'electricity_check_fee.numeric' => '验电费必须是数字',
            'electricity_check_fee.min' => '验电费不能小于0',
            'operation_fee_charging_weight.numeric' => '操作费-计费重必须是数字',
            'operation_fee_charging_weight.min' => '操作费-计费重不能小于0',
            'charter_fee.numeric' => '包车费必须是数字',
            'charter_fee.min' => '包车费不能小于0',
            'hk_registration_fee.numeric' => '香港登记费必须是数字',
            'hk_registration_fee.min' => '香港登记费不能小于0',
            'cross_border_transfer_fee.numeric' => '境外卡转费必须是数字',
            'cross_border_transfer_fee.min' => '境外卡转费不能小于0',
            'insurance_fee.numeric' => '保险费必须是数字',
            'insurance_fee.min' => '保险费不能小于0',
            'sea_freight.numeric' => '海运运费必须是数字',
            'sea_freight.min' => '海运运费不能小于0',
            'ground_operation_fee_air.numeric' => '地面操作费-空运必须是数字',
            'ground_operation_fee_air.min' => '地面操作费-空运不能小于0',
            'total_amount.numeric' => '总额必须是数字',
            'total_amount.min' => '总额不能小于0',
        ]);
        
        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }

        // 根据提单号查询提单ID
        $takeOrder = TakeOrderModel::where('sn', $request->input('take_order_sn'))->first();
        if (!$takeOrder) {
            return $this->error('主单号不存在');
        }
        
        try {
            DB::beginTransaction();
            
            $receivable = new ReceivableTemplate1Model();
            $receivable->business_date = $request->input('business_date');
            $receivable->take_order_id = $takeOrder->id;
            $receivable->origin = $request->input('origin');
            $receivable->destination = $request->input('destination');
            $receivable->charging_weight = $request->input('charging_weight');
            $receivable->gross_weight = $request->input('gross_weight');
            $receivable->volume_weight = $request->input('volume_weight');
            $receivable->big_package = $request->input('big_package');
            $receivable->volume = $request->input('volume');
            $receivable->air_freight_unit_price = $request->input('air_freight_unit_price');
            $receivable->currency = $request->input('currency');
            $receivable->air_freight = $request->input('air_freight');
            $receivable->master_bill_fee = $request->input('master_bill_fee');
            $receivable->electricity_check_fee = $request->input('electricity_check_fee');
            $receivable->operation_fee_charging_weight = $request->input('operation_fee_charging_weight');
            $receivable->charter_fee = $request->input('charter_fee');
            $receivable->hk_registration_fee = $request->input('hk_registration_fee');
            $receivable->cross_border_transfer_fee = $request->input('cross_border_transfer_fee');
            $receivable->insurance_fee = $request->input('insurance_fee');
            $receivable->sea_freight = $request->input('sea_freight');
            $receivable->ground_operation_fee_air = $request->input('ground_operation_fee_air');
            $receivable->total_amount = $request->input('total_amount') ?? $this->calculateTotalAmount($request->all());
            $receivable->status = ReceivableTemplate1Model::STATUS_UNPAID;
            $receivable->created_admin_id = Auth::id();
            $receivable->save();
            
            DB::commit();
            
            return $this->success($receivable, '添加成功');
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error('添加失败：' . $e->getMessage());
        }
    }
    
    /**
     * 更新模板1应收账款
     *
     * @param Request $request
     * @param int $id
     * @return JsonResponse
     */
    public function update(Request $request, int $id): JsonResponse
    {
        $receivable = ReceivableTemplate1Model::find($id);
        
        if (!$receivable) {
            return $this->error('记录不存在');
        }
        
        $validator = Validator::make($request->all(), [
            'business_date' => 'sometimes|required|date',
            'take_order_sn' => 'sometimes|required|string',
            'origin' => 'sometimes|required|string|max:100',
            'destination' => 'sometimes|required|string|max:100',
            'charging_weight' => 'sometimes|required|numeric|min:0',
            'currency' => 'sometimes|required|string|max:20',
            'gross_weight' => 'nullable|numeric|min:0',
            'volume_weight' => 'nullable|numeric|min:0',
            'big_package' => 'nullable|integer|min:0',
            'volume' => 'nullable|numeric|min:0',
            'air_freight_unit_price' => 'nullable|numeric|min:0',
            'air_freight' => 'nullable|numeric|min:0',
            'master_bill_fee' => 'nullable|numeric|min:0',
            'electricity_check_fee' => 'nullable|numeric|min:0',
            'operation_fee_charging_weight' => 'nullable|numeric|min:0',
            'charter_fee' => 'nullable|numeric|min:0',
            'hk_registration_fee' => 'nullable|numeric|min:0',
            'cross_border_transfer_fee' => 'nullable|numeric|min:0',
            'insurance_fee' => 'nullable|numeric|min:0',
            'sea_freight' => 'nullable|numeric|min:0',
            'ground_operation_fee_air' => 'nullable|numeric|min:0',
            'total_amount' => 'nullable|numeric|min:0',
            'status' => 'nullable|in:1,2,3',
        ], [
            'business_date.required' => '业务日期不能为空',
            'business_date.date' => '业务日期格式不正确',
            'take_order_sn.required' => '主单号不能为空',
            'take_order_sn.string' => '主单号必须是字符串',
            'origin.required' => '起始港不能为空',
            'origin.string' => '起始港必须是字符串',
            'origin.max' => '起始港不能超过100个字符',
            'destination.required' => '目的港不能为空',
            'destination.string' => '目的港必须是字符串',
            'destination.max' => '目的港不能超过100个字符',
            'charging_weight.required' => '计费重不能为空',
            'charging_weight.numeric' => '计费重必须是数字',
            'charging_weight.min' => '计费重不能小于0',
            'currency.required' => '币种不能为空',
            'currency.string' => '币种必须是字符串',
            'currency.max' => '币种不能超过20个字符',
            'gross_weight.numeric' => '毛重必须是数字',
            'gross_weight.min' => '毛重不能小于0',
            'volume_weight.numeric' => '体积重必须是数字',
            'volume_weight.min' => '体积重不能小于0',
            'big_package.integer' => '大包数量必须是整数',
            'big_package.min' => '大包数量不能小于0',
            'volume.numeric' => '体积必须是数字',
            'volume.min' => '体积不能小于0',
            'air_freight_unit_price.numeric' => '空运单价必须是数字',
            'air_freight_unit_price.min' => '空运单价不能小于0',
            'air_freight.numeric' => '空运费必须是数字',
            'air_freight.min' => '空运费不能小于0',
            'master_bill_fee.numeric' => '主单费必须是数字',
            'master_bill_fee.min' => '主单费不能小于0',
            'electricity_check_fee.numeric' => '验电费必须是数字',
            'electricity_check_fee.min' => '验电费不能小于0',
            'operation_fee_charging_weight.numeric' => '操作费-计费重必须是数字',
            'operation_fee_charging_weight.min' => '操作费-计费重不能小于0',
            'charter_fee.numeric' => '包车费必须是数字',
            'charter_fee.min' => '包车费不能小于0',
            'hk_registration_fee.numeric' => '香港登记费必须是数字',
            'hk_registration_fee.min' => '香港登记费不能小于0',
            'cross_border_transfer_fee.numeric' => '境外卡转费必须是数字',
            'cross_border_transfer_fee.min' => '境外卡转费不能小于0',
            'insurance_fee.numeric' => '保险费必须是数字',
            'insurance_fee.min' => '保险费不能小于0',
            'sea_freight.numeric' => '海运运费必须是数字',
            'sea_freight.min' => '海运运费不能小于0',
            'ground_operation_fee_air.numeric' => '地面操作费-空运必须是数字',
            'ground_operation_fee_air.min' => '地面操作费-空运不能小于0',
            'total_amount.numeric' => '总额必须是数字',
            'total_amount.min' => '总额不能小于0',
            'status.in' => '状态值无效',
        ]);
        
        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }
        
        try {
            DB::beginTransaction();

            // 如果更新提单号，需要先查询对应的提单ID
            if ($request->filled('take_order_sn')) {
                $takeOrder = TakeOrderModel::where('sn', $request->input('take_order_sn'))->first();
                if (!$takeOrder) {
                    return $this->error('主单号不存在');
                }
                $receivable->take_order_id = $takeOrder->id;
            }
            
            // 更新字段
            $fields = [
                'business_date', 'origin', 'destination',
                'charging_weight', 'gross_weight', 'volume_weight', 'big_package',
                'volume', 'air_freight_unit_price', 'currency', 'air_freight',
                'master_bill_fee', 'electricity_check_fee', 'operation_fee_charging_weight',
                'charter_fee', 'hk_registration_fee', 'cross_border_transfer_fee',
                'insurance_fee', 'sea_freight', 'ground_operation_fee_air',
                'total_amount', 'status'
            ];
            
            foreach ($fields as $field) {
                if ($request->filled($field)) {
                    $receivable->$field = $request->input($field);
                }
            }
            
            // 如果未提供总额但提供了其他费用字段，重新计算总额
            if (!$request->filled('total_amount') && $this->hasFeeFieldsUpdated($request->all())) {
                $receivable->total_amount = $this->calculateTotalAmount($receivable->toArray());
            }
            
            $receivable->save();
            
            DB::commit();
            
            return $this->success($receivable, '更新成功');
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error('更新失败：' . $e->getMessage());
        }
    }
    
    /**
     * 删除模板1应收账款
     *
     * @param int $id
     * @return JsonResponse
     */
    public function delete(int $id): JsonResponse
    {
        $receivable = ReceivableTemplate1Model::find($id);
        
        if (!$receivable) {
            return $this->error('记录不存在');
        }
        
        try {
            $receivable->delete();
            return $this->success([], '删除成功');
        } catch (\Exception $e) {
            return $this->error('删除失败：' . $e->getMessage());
        }
    }
    
    /**
     * 判断是否有费用字段被更新
     *
     * @param array $data
     * @return bool
     */
    private function hasFeeFieldsUpdated(array $data): bool
    {
        $feeFields = [
            'air_freight', 'master_bill_fee', 'electricity_check_fee',
            'operation_fee_charging_weight', 'charter_fee', 'hk_registration_fee',
            'cross_border_transfer_fee', 'insurance_fee', 'sea_freight',
            'ground_operation_fee_air'
        ];
        
        foreach ($feeFields as $field) {
            if (isset($data[$field])) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * 计算总金额
     *
     * @param array $data
     * @return float
     */
    private function calculateTotalAmount(array $data): float
    {
        $totalAmount = 0;
        
        $feeFields = [
            'air_freight', 'master_bill_fee', 'electricity_check_fee',
            'operation_fee_charging_weight', 'charter_fee', 'hk_registration_fee',
            'cross_border_transfer_fee', 'insurance_fee', 'sea_freight',
            'ground_operation_fee_air'
        ];
        
        foreach ($feeFields as $field) {
            if (isset($data[$field]) && is_numeric($data[$field])) {
                $totalAmount += floatval($data[$field]);
            }
        }
        
        return round($totalAmount, 2);
    }
    
    /**
     * 导出模板1应收账款
     *
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
     */
    public function export(Request $request)
    {
        return Excel::download(new ReceivableTemplate1Export($request), '应收账款模板1_' . date('Y-m-d_H-i-s') . '.xlsx');
    }
} 